package common

import (
	"context"
	"errors"
	"fmt"
	"github.com/chromedp/cdproto/network"
	"github.com/chromedp/chromedp"
	"io/ioutil"
	"log"
	"os"
	"time"
)

type AutoOptionI interface {
	Login() error
	LoadCookies() chromedp.ActionFunc
	RemoveCookies() error
	SaveCookies() chromedp.ActionFunc
	Task()
}

type AutoOptionS struct {
	Url    string
	Cookie string
	Ctx    context.Context
	Cancel context.CancelFunc
}

func (a *AutoOptionS) Login() error {
	fmt.Println("---------auto login")
	return nil
}

func (a *AutoOptionS) LoadCookies() chromedp.ActionFunc {
	return func(ctx context.Context) (err error) {
		// 如果cookies临时文件不存在则直接跳过
		if _, _err := os.Stat(a.Cookie); os.IsNotExist(_err) {
			fmt.Println("error cookie file not here")
			return errors.New("cookie not exist" + a.Cookie)
		}

		// 如果存在则读取cookies的数据
		cookiesData, err := ioutil.ReadFile(a.Cookie)
		if err != nil {
			fmt.Println("error cookie read file")
			return err
		}

		// 反序列化
		cookiesParams := network.SetCookiesParams{}
		if err = cookiesParams.UnmarshalJSON(cookiesData); err != nil {
			fmt.Println("error cookie json unmarshl")
			return err
		}

		// 设置cookies
		return network.SetCookies(cookiesParams.Cookies).Do(ctx)
	}
}

func (a *AutoOptionS) RemoveCookies() error {
	if _, _err := os.Stat(a.Cookie); !os.IsNotExist(_err) {
		err := os.Remove(a.Cookie)
		if err != nil {
			fmt.Println("error deleting cookie")
			return errors.New("err:error deleting cookie")
		}
		fmt.Println("info delete expired cookies...")
	} else {
		fmt.Println("info the cookie does not exist...")
	}
	return nil
}

func (a *AutoOptionS) SaveCookies() chromedp.ActionFunc {
	fmt.Println("====auto save cookie")
	return nil
}

func (a *AutoOptionS) Task() {
	return
}

func (a *AutoOptionS) LoginContext(boo bool) (context.Context, context.CancelFunc) {
	options := []chromedp.ExecAllocatorOption{
		chromedp.Flag("headless", boo), // 是否打开浏览器调试
		chromedp.UserAgent("Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"), // 设置User-Agent
	}
	options = append(chromedp.DefaultExecAllocatorOptions[:], options...)
	// chromdp依赖context上限传递参数
	ctx, cancel := chromedp.NewExecAllocator(
		context.Background(),
		// 以默认配置的数组为基础，覆写headless参数
		// 当然也可以根据自己的需要进行修改，这个flag是浏览器的设置
		options...,
	)
	ctx, cancel = chromedp.NewContext(
		ctx,
		// 设置日志方法
		chromedp.WithLogf(log.Printf),
	)
	return ctx, cancel
}

func (s *AutoOptionS) WaitTimes(timeout int) {
	s.Ctx, s.Cancel = context.WithTimeout(s.Ctx, time.Second*time.Duration(timeout))
	go func() {
		select {
		case <-s.Ctx.Done():
			fmt.Println("error timeout!!!")
			s.Cancel()
		}

	}()
}

func NewAutoOption(boo bool) AutoOptionI {
	return &AutoOptionS{}
}
